home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Better AD security / Source / InstallCode.c < prev    next >
Text File  |  1996-06-21  |  13KB  |  555 lines

  1. /*    NAME:
  2.         InstallCode.c
  3.  
  4.     WRITTEN BY:
  5.         Dair Grant
  6.                 
  7.     DESCRIPTION:
  8.         Routines for installing various code resources.
  9.         
  10.     ___________________________________________________________________________
  11. */
  12. //=============================================================================
  13. //        Include files
  14. //-----------------------------------------------------------------------------
  15. #include <Memory.h>
  16. #include <Gestalt.h>
  17. #include <Errors.h>
  18. #include <Resources.h>
  19. #include <Shutdown.h>
  20. #include <Timer.h>
  21. #include "ES.h"
  22. #include "ES Address Table.h"
  23. #include "InstallCode.h"
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39. //=============================================================================
  40. //        Private function prototypes
  41. //-----------------------------------------------------------------------------
  42. OSErr    InstallTrapPatch(short i, Ptr theCode);
  43. OSErr    InstallGestaltSelector(short i, Ptr theCode);
  44. OSErr    InstallShutdownTask(short i, Ptr theCode);
  45. OSErr    InstallVBLTask(short i, Ptr theCode);
  46. OSErr    InstallLowMemFilter(short i, Ptr theCode);
  47. OSErr    InstallCodeBlock(short i, Ptr theCode);
  48. OSErr    InstallTimeManagerTask(short i, Ptr theCode);
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. //=============================================================================
  65. //        Global variables
  66. //-----------------------------------------------------------------------------
  67. extern ESParamBlock            gTheParamBlock;
  68. extern ESAddressTable        *gTheESAddressTable;
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84. //=============================================================================
  85. //        InstallCode : Install a code resource depending on its type.                                                                 
  86. //-----------------------------------------------------------------------------
  87. //        Note :    We get the index of something in gTheParamBlock.theCodeResources
  88. //                and case out on its type to do the installation. If any error
  89. //                occurs, we return the error code - our caller fills in the
  90. //                details in gTheParamBlock.
  91. //-----------------------------------------------------------------------------
  92. OSErr InstallCode(short i)
  93. {    Handle        theHnd;
  94.     OSErr        theErr;
  95.     Ptr            theCode;
  96.     
  97.     
  98.  
  99.  
  100.     // Get the code resource we're after, and return if it wasn't there.
  101.     theHnd = Get1Resource(gTheParamBlock.theCodeResources[i].resType,
  102.                           gTheParamBlock.theCodeResources[i].resID);
  103.     if (theHnd == nil)
  104.         return(resNotFound);
  105.  
  106.  
  107.     
  108.     // Unlock the resource, compact the heap, then lock it down. We then
  109.     // detach it so it stays around after Extension Shell is gone.
  110.     HUnlock(theHnd);
  111.     ResrvMem(GetHandleSize(theHnd));
  112.     HLock(theHnd);
  113.     DetachResource(theHnd);
  114.  
  115.  
  116.  
  117.     // Get a clean address from the handle
  118.     theCode = (Ptr) StripAddress(*theHnd);
  119.  
  120.  
  121.  
  122.     // Now case out on the type of the code, and call the install routine
  123.     switch(gTheParamBlock.theCodeResources[i].codeType) {
  124.         case kTrapPatchType:
  125.              theErr = InstallTrapPatch(i, theCode);
  126.              break;
  127.              
  128.         case kGestaltSelectorType:
  129.              theErr = InstallGestaltSelector(i, theCode);
  130.              break;
  131.              
  132.         case kShutdownTaskType:
  133.              theErr = InstallShutdownTask(i, theCode);
  134.              break;
  135.              
  136.         case kVBLTaskType:
  137.              theErr = InstallVBLTask(i, theCode);
  138.              break;
  139.         
  140.         case kLowMemFilterType:
  141.              theErr = InstallLowMemFilter(i, theCode);
  142.              break;
  143.         
  144.         case kCodeBlockType:
  145.              theErr = InstallCodeBlock(i, theCode);
  146.              break;
  147.         
  148.         case kTimeManagerTaskType:
  149.              theErr = InstallTimeManagerTask(i, theCode);
  150.              break;
  151.         
  152.         default:
  153.              theErr = noErr;
  154.     }
  155.  
  156.     
  157.     // Return any errors that occurred    
  158.     return(theErr);
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174. //=============================================================================
  175. //        InstallESAddressTable : Install an address table.
  176. //-----------------------------------------------------------------------------
  177. //        Note :    We install the Gestalt selector, call Gestalt to obtain the
  178. //                address of the address table, and leave the result in
  179. //                gTheESAddressTable.
  180. //
  181. //                Because the address table is so fundamental, any failure
  182. //                to load, install, or call it drops us into MacsBug.
  183. //
  184. //                We also initialse the magicNumber and versionNumber fields.
  185. //-----------------------------------------------------------------------------
  186. void InstallESAddressTable(void)
  187. {    Handle            theHnd;
  188.     OSErr            theErr;
  189.     ProcPtr            theCode;    
  190.  
  191.  
  192.  
  193.     // Load the AddressTable Gestalt selector, and install it with NewGestalt.
  194.     theHnd = GetResource(kAddrsTableCodeType, kAddrsTableCodeID);
  195.     if (theHnd == nil)
  196.         DebugStr("\pExtension Shell - couldn't find Address Table resource");
  197.     
  198.     
  199.     // We have it, so lock it in place
  200.     HUnlock(theHnd);
  201.     ResrvMem(GetHandleSize(theHnd));
  202.     HLock(theHnd);
  203.     DetachResource(theHnd);
  204.     
  205.     
  206.     // Get a clean address from the handle
  207.     theCode = (ProcPtr) StripAddress(*theHnd);
  208.     
  209.     
  210.     // Install the address table as a Gestalt selector
  211.     theErr = NewGestalt(gTheParamBlock.addressTableSelector,
  212.                                 NewSelectorFunctionProc(theCode));
  213.     if (theErr != noErr)
  214.         DebugStr("\pExtension Shell - couldn't install AddressTable");
  215.         
  216.  
  217.     // Call Gestalt to get the address of the address table and initialise
  218.     // the magicNumber and versionNumber fields.
  219.     theErr = Gestalt(gTheParamBlock.addressTableSelector, (long *) &gTheESAddressTable);
  220.     if (theErr != noErr)
  221.         DebugStr("\pExtension Shell - couldn't call AddressTable");
  222.     else
  223.         {
  224.         gTheESAddressTable->magicNumber   = 0xDEADBEEF;
  225.         gTheESAddressTable->versionNumber = 0xFEEDFACE;
  226.         }
  227. }
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. //=============================================================================
  244. //        InstallTrapPatch : Install a trap patch.                                                         
  245. //-----------------------------------------------------------------------------
  246. //        Note :    Given a trap word and a pointer to the new routine, we save
  247. //                the original entry in the dispatch table and insert the new
  248. //                one.
  249. //
  250. //                We assume that the trap *is* implemented. If globalPatch is
  251. //                true, the patch is applied to all applications (this is the
  252. //                default behaviour). If globalPatch is false, the patch only
  253. //                takes affect in the application appName. (THIS FEATURE IS
  254. //                NOT IMPLEMENTED YET)
  255. //-----------------------------------------------------------------------------
  256. OSErr InstallTrapPatch(short i, Ptr theCode)
  257. {    short        trapWord;
  258.     TrapType    trapType;
  259.     ProcPtr        oldCodeAddress;
  260.     
  261.     
  262.     
  263.     // Find out what we need to know
  264.      trapWord = gTheParamBlock.theCodeResources[i].theCodeThing.theTrapPatch.trapWord;
  265.     trapType = (trapWord & 0x0800) ? ToolTrap : OSTrap;
  266.  
  267.  
  268.     // Replace the old value in the dispatch table with the new value.
  269.     oldCodeAddress = (ProcPtr) StripAddress((Ptr) NGetTrapAddress(trapWord, trapType));
  270.     NSetTrapAddress((UniversalProcPtr) theCode, trapWord, trapType);
  271.     
  272.     
  273.     
  274.     // Handle globalPatch and appName
  275.     //
  276.     // THIS FEATURE IS NOT IMPLEMENTED YET - IT WOULD NEED SOME KIND OF
  277.     // GENERIC EXTENSION SHELL PATCH TO SOMETHING LIKE _INITALLPACKS OR
  278.     // _INITGRAF, AND THEN THE APPLICATION OF PATCHES DEPENDING ON
  279.     // THE APPLICATION BEING EXECUTED.
  280.     //
  281.     //
  282.     
  283.     
  284.     
  285.     // Fill in the entry in the address table and save the address of the new code.
  286.     gTheESAddressTable->theTable[i]                    = oldCodeAddress;
  287.     gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  288.  
  289.  
  290.     // Return any errors
  291.     return(noErr);
  292. }
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308. //=============================================================================
  309. //        InstallGestaltSelector : Install a Gestalt Selector.                                                         
  310. //-----------------------------------------------------------------------------
  311. OSErr InstallGestaltSelector(short i, Ptr theCode)
  312. {    OSErr                    theErr;
  313.     SelectorFunctionUPP        theUPP;
  314.     AGestaltSelector        *theGestaltInfo;
  315.  
  316.  
  317.  
  318.  
  319.     // Find out what we need to know
  320.     theGestaltInfo = &gTheParamBlock.theCodeResources[i].theCodeThing.theGestaltSelector;
  321.     theUPP = NewSelectorFunctionProc(theCode);
  322.     
  323.  
  324.     
  325.     // Try and install the routine
  326.     theErr = NewGestalt(theGestaltInfo->theSelector, theUPP);
  327.  
  328.     
  329.     
  330.     // If the selector exists, replace it if we're allowed to, and save
  331.     // the address of the old routine in the address table
  332.     if (theErr == gestaltDupSelectorErr && theGestaltInfo->overwriteExistingSelector)
  333.         theErr = ReplaceGestalt(theGestaltInfo->theSelector, theUPP,
  334.                                 (SelectorFunctionUPP *) &gTheESAddressTable->theTable[i]);
  335.     
  336.     
  337.     
  338.     // If there wasn't a problem, save the address of the new code. The address
  339.     // table is only used if we need to get access to the old Gestalt routine.
  340.     if (theErr == noErr)
  341.         gTheParamBlock.theCodeResources[i].theAddress = theCode;
  342.         
  343.         
  344.     
  345.     // Return any errors
  346.     return(theErr);
  347. }
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363. //=============================================================================
  364. //        InstallShutdownTask : Install a Shutdown Task.                                                         
  365. //-----------------------------------------------------------------------------
  366. OSErr InstallShutdownTask(short i, Ptr theCode)
  367. {
  368.  
  369.  
  370.     // Install the task with its flags and save the address in gTheParamBlock.
  371.     // We don't use the address table at all.
  372.     ShutDwnInstall(NewShutDwnProc(theCode),
  373.                    gTheParamBlock.theCodeResources[i].theCodeThing.theShutdownTask.theFlags);
  374.     gTheParamBlock.theCodeResources[i].theAddress = theCode;
  375.  
  376.  
  377.     // Return any errors
  378.     return(noErr);
  379. }
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395. //=============================================================================
  396. //        InstallVBLTask : Install a VBL task.                                                         
  397. //-----------------------------------------------------------------------------
  398. OSErr InstallVBLTask(short i, Ptr theCode)
  399. {    VBLTask         *theVblPtr;
  400.     OSErr            theErr;
  401.     
  402.     
  403.     
  404.     
  405.     // Allocate a little block of memory in the System Heap for the task information
  406.     theVblPtr = (VBLTask*) NewPtrSys(sizeof(VBLTask));
  407.     
  408.     
  409.     
  410.     // Fill in the fields, and install it as a VBL task
  411.     theVblPtr->qType    = vType;
  412.     theVblPtr->vblAddr  = NewVBLProc(theCode);
  413.     theVblPtr->vblCount = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblCount;
  414.     theVblPtr->vblPhase = gTheParamBlock.theCodeResources[i].theCodeThing.theVBLTask.vblPhase;
  415.     theErr = VInstall((QElemPtr) theVblPtr);
  416.     
  417.     
  418.     
  419.     // Save the address of the VBLTask structure in the address table and the param block
  420.     if (theErr == noErr)
  421.         {
  422.         gTheESAddressTable->theTable[i]                    = (ProcPtr) theVblPtr;
  423.         gTheParamBlock.theCodeResources[i].theAddress    = (Ptr) theVblPtr;
  424.         }
  425.     
  426.     
  427.     // Return any errors
  428.     return(theErr);
  429. }
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445. //=============================================================================
  446. //        InstallLowMemFilter : Install a low-memory filter.                                                         
  447. //-----------------------------------------------------------------------------
  448. OSErr InstallLowMemFilter(short i, Ptr theCode)
  449. {    ProcPtr        theEntryPoint;
  450.     
  451.  
  452.  
  453.     
  454.     // Get the address of the filter chain.
  455.     theEntryPoint = (ProcPtr) gTheParamBlock.theCodeResources[i].theCodeThing.theLowMemFilter.theEntryPoint;
  456.     
  457.     
  458.     
  459.     // Save the address currently at the front of the chain in the address table
  460.     // and save ourselves in the param block.
  461.     gTheESAddressTable->theTable[i]                    = (ProcPtr) *((void **) theEntryPoint);
  462.     gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  463.     
  464.     
  465.     // Insert ourselves into the front of the chain
  466.     *((long *) theEntryPoint) = (long) theCode;
  467.  
  468.  
  469.     // Return any errors
  470.     return(noErr);
  471. }
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487. //=============================================================================
  488. //        InstallCodeBlock : Install a block of code.                                                         
  489. //-----------------------------------------------------------------------------
  490. OSErr InstallCodeBlock(short i, Ptr theCode)
  491. {    
  492.     
  493.     
  494.     // Set the reserved field to some value
  495.     gTheParamBlock.theCodeResources[i].theCodeThing.theCodeBlock.refCon = 0xDEADBEEF;
  496.  
  497.     
  498.     // Save the address of the code block in the address table and the param block
  499.     gTheESAddressTable->theTable[i]                    = (ProcPtr) theCode;
  500.     gTheParamBlock.theCodeResources[i].theAddress    = theCode;
  501.  
  502.  
  503.     // Return any errors
  504.     return(noErr);
  505. }
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521. //=============================================================================
  522. //        InstallTimeManagerTask : Install a Time Manager task.                                                         
  523. //-----------------------------------------------------------------------------
  524. OSErr InstallTimeManagerTask(short i, Ptr theCode)
  525. {    TMTask             *theTaskPtr;
  526.  
  527.  
  528.  
  529.  
  530.     // Allocate a little block of memory in the System Heap for the task information
  531.     theTaskPtr = (TMTask*) NewPtrSys(sizeof(TMTask));
  532.     
  533.     
  534.     
  535.     // Fill in the fields, and install it as an Time Manager task. We don't install
  536.     // it as with InsXTime because we probably won't need that accurate timing.
  537.     theTaskPtr->tmAddr    = (TimerUPP) theCode;
  538.     theTaskPtr->tmCount    = 0;
  539.     InsTime((QElemPtr) theTaskPtr);
  540.     PrimeTime((QElemPtr) theTaskPtr,
  541.                 gTheParamBlock.theCodeResources[i].theCodeThing.theTimeManagerTask.theDelay);
  542.     
  543.     
  544.     
  545.     // Save the address of the TMTask structure in the address table and the param block
  546.     gTheESAddressTable->theTable[i]                    = (ProcPtr) theTaskPtr;
  547.     gTheParamBlock.theCodeResources[i].theAddress    = (Ptr) theTaskPtr;
  548.     
  549.     
  550.     
  551.     // Return any errors
  552.     return(noErr);
  553. }
  554.